Syntax10.Scn.Fnt Syntax10i.Scn.Fnt StampElems Alloc 11 Nov 94 Syntax10b.Scn.Fnt MODULE DialogAnalogClocks; (** Markus Knasm ller 14 Sep 94 - (* This sourcecode uses parts of ClockElems - gri 18.3.91 *) IMPORT DialogClocks, DialogFrames, Dialogs, Display, In, Math, Oberon, Printer; CONST W* = 65; H* = W; Rmin = 12; Rdef = 8.2; black = 15; TYPE Item* = POINTER TO ItemDesc; ItemDesc* = RECORD(DialogClocks.ItemDesc) END; VAR sin, cos: ARRAY 60 OF REAL; Line: PROCEDURE (f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER); Circle: PROCEDURE (f: Display.Frame; x0, y0, r, color, mode: INTEGER); PROCEDURE Min (x, y: INTEGER): INTEGER; BEGIN IF x < y THEN RETURN x ELSE RETURN y END END Min; PROCEDURE Init; VAR i: INTEGER; BEGIN i := 0; WHILE i < 60 DO sin[i] := Math.sin (2 * Math.pi / 60 * i); cos[i] := Math.cos (2 * Math.pi / 60 * i); INC (i) END END Init; PROCEDURE Format (time: LONGINT; VAR sec, min, hour, hourm: INTEGER); BEGIN hour := SHORT (time DIV 4096 MOD 32); min := SHORT (time DIV 64 MOD 64); sec := SHORT (time MOD 64); hourm := (hour MOD 12) * 5 + min DIV 12 END Format; (* graphics *) PROCEDURE SCircle(f: Display.Frame; x0, y0, r, color, mode: INTEGER); VAR x, y, dx, dy, d: INTEGER; PROCEDURE Dot4(x1, x2, y1, y2, color, mode: INTEGER); BEGIN Display.DotC (f, color, x1, y1, mode); Display.DotC (f, color, x1, y2, mode); Display.DotC (f, color, x2, y1, mode); Display.DotC (f, color, x2, y2, mode) END Dot4; BEGIN x := r; y := 0; dx := 8*(x-1); dy := 8*y+4; d := 1-4*r; WHILE x > y DO Dot4(x0-x, x0+x, y0-y, y0+y, color, mode); Dot4(x0-y, x0+y, y0-x, y0+x, color, mode); INC(d, dy); INC(dy, 8); INC(y); IF d >= 0 THEN DEC(d, dx); DEC(dx, 8); DEC(x) END END; IF x = y THEN Dot4(x0-x, x0+x, y0-y, y0+y, color, mode) END END SCircle; PROCEDURE SLine(f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER); VAR x, y, dx, dy, d, inc: INTEGER; BEGIN IF (y2 - y1) < (x1 - x2) THEN x := x1; x1 := x2; x2 := x; y := y1; y1 := y2; y2 := y END; dx := 2 * (x2 - x1); dy := 2 * (y2 - y1); x := x1; y := y1; inc := 1; IF dy > dx THEN d := dy DIV 2; IF dx < 0 THEN inc := -1; dx := -dx END; WHILE y <= y2 DO Display.DotC (f, color, x, y, mode); INC (y); DEC (d, dx); IF d < 0 THEN INC (d, dy); INC (x, inc) END END ELSE d := dx DIV 2; IF dy < 0 THEN inc := -1; dy := -dy END; WHILE x <= x2 DO Display.DotC (f, color, x, y, mode); INC (x); DEC (d, dy); IF d < 0 THEN INC (d, dx); INC (y, inc) END END END END SLine; PROCEDURE PCircle (f: Display.Frame; x0, y0, r, color, mode: INTEGER); BEGIN Printer.Circle (x0, y0, r) END PCircle; PROCEDURE PLine (f: Display.Frame; x1, y1, x2, y2, color, mode: INTEGER); BEGIN Printer.Line (x1, y1, x2, y2) END PLine; (* view update *) PROCEDURE Line2(f: Display.Frame; ang: INTEGER; x0, y0, r1, r2, color: INTEGER); VAR x1, y1, x2, y2: INTEGER; BEGIN ang := (15-ang) MOD 60; x1 := SHORT (ENTIER(r1 * cos[ang] + 0.5)); y1 := SHORT (ENTIER(r1 * sin[ang] + 0.5)); x2 := SHORT (ENTIER(r2 * cos[ang] + 0.5)); y2 := SHORT (ENTIER(r2 * sin[ang] + 0.5)); Line (f, x0 + x1, y0 + y1, x0 + x2, y0 + y2, color, Display.invert) END Line2; PROCEDURE Line3(f: Display.Frame; ang: INTEGER; x0, y0, r1, r2, color: INTEGER); VAR x1, y1, x2, y2: INTEGER; BEGIN ang := (15-ang) MOD 60; x1 := SHORT (ENTIER(r1 * cos[ang] + 0.5)); y1 := SHORT (ENTIER(r1 * sin[ang] + 0.5)); x2 := SHORT (ENTIER(r2 * cos[ang] + 0.5)); y2 := SHORT (ENTIER(r2 * sin[ang] + 0.5)); Line (f, x0 + x1, y0 + y1, x0 + x2, y0 + y2, color, Display.paint) END Line3; PROCEDURE (c: Item) Draw* (x, y: INTEGER; f: Display.Frame); (** displays the object at (x, y) in frame f *) VAR r, rh, rm, rs, i, sec, min, hour, hourm, mode, ox, oy, w, h: INTEGER; BEGIN Line := SLine; Circle := SCircle; c.GetDim (ox, oy, w, h); Display.ReplConstC (f, f(DialogFrames.Frame).col, x, y, w, h, Display.paint); r := Min (w - 1 , h - 1) DIV 2; x := x + r; y := y + r; IF c.selected THEN mode := Display.invert ELSE mode := Display.replace END; IF r >= Rmin THEN rh := 7 * r DIV 11; rm := 9 * r DIV 11; rs := 10 * r DIV 11; i := 0; WHILE i < 60 DO Line3 (f, i, x, y, rm, r, black); INC (i, 5) END; Format (DialogClocks.old.timeStamp, sec, min, hour, hourm); Line2 (f, sec, x, y, rm-r, rs, black); Line2 (f, min, x, y, 0, rm, black); Line2 (f, hourm, x, y, 0, rh, black); Circle (f, x, y, 2, black, mode) END; Circle(f, x, y, r, black, mode) END Draw; PROCEDURE (c: Item) Print* (x, y: INTEGER); (** prints the object at printer coordinates (x, y) *) VAR ox, oy, w, h, r, sec, min, hour, hourm, mode, i, rh, rm, rs: INTEGER; f: Display.Frame; BEGIN Line := PLine; Circle := PCircle; c.GetPDim (ox, oy, w, h); r := Min (w - 1 , h - 1) DIV 2; x := x + r; y := y + r; IF r >= Rmin THEN rh := 7 * r DIV 11; rm := 9 * r DIV 11; rs := 10 * r DIV 11; i := 0; WHILE i < 60 DO Line2 (f, i, x, y, rm, r, black); INC (i, 5) END; Format (DialogClocks.old.timeStamp, sec, min, hour, hourm); Line2 (f, sec, x, y, rm-r, rs, black); Line2 (f, min, x, y, 0, rm, black); Line2 (f, hourm, x, y, 0, rh, black); Circle (f, x, y, SHORT (2 * Dialogs.dUnit DIV Dialogs.pUnit), black, Display.paint) END; Circle(f, x, y, r, black, mode) END Print; PROCEDURE (c: Item) Redraw* (f: Display.Frame; x, y: INTEGER; old, new: DialogClocks.Time); (** handles messages which were sent to frame f *) VAR rh, rm, rs, olds, oldm, oldh, oldhm, news, newm, newh, newhm, ox, oy, w, h, r, mode: INTEGER; BEGIN c.GetDim (ox, oy, w, h); r := Min (w - 1, h - 1) DIV 2; x := x + r; y := y + r; IF c.selected THEN RETURN END; Line := SLine; Circle := SCircle; IF r >= Rmin THEN rh := 7*r DIV 11; rm := 9*r DIV 11; rs := 10*r DIV 11; Format (old.timeStamp, olds, oldm, oldh, oldhm); Format (new.timeStamp, news, newm, newh, newhm); IF olds # news THEN Line2 (f, olds, x, y, rm-r, rs, black); Line2(f, news, x, y, rm-r, rs, black) END; IF oldm # newm THEN Line2(f, oldm, x, y, 0, rm, black); Line2(f, newm, x, y, 0, rm, black) END; IF oldhm # newhm THEN Line2(f, oldhm, x, y, 0, rh, black); Line2(f, newhm, x, y, 0, rh, black) END; Circle (f, x, y, 2, black, mode) END END Redraw; PROCEDURE (c: Item) Copy* (VAR dup: Dialogs.Object); (** allocates dup and makes a deep copy of o. Before calling this methode dup should be equal NIL *) VAR x: Item; BEGIN IF dup = NIL THEN NEW (x); dup := x ELSE x := dup(Item) END; c.Copy^ (dup); END Copy; PROCEDURE Insert*; (** Insert ([name] [x y w h] | ^ ) inserts a clock - item in the panel containing the caret position *) VAR x, y, x1, y1, w, h: INTEGER; c: Item; p: Dialogs.Panel; name: ARRAY 64 OF CHAR; BEGIN NEW (c); DialogFrames.GetCaretPosition (p, x, y); IF (p # NIL) THEN c.Init; In.Open; In.Name (name); IF ~In.Done THEN COPY ("", name); In.Open END; c.SetName (name); In.Int (x1); In.Int (y1); In.Int (w); In.Int (h); IF ~In.Done THEN x1 := x; y1 := y; w := W; h := H ELSE IF w < 0 THEN w := W END; IF h < 0 THEN h := H END END; c.SetDim (x, y, W, H, FALSE); p.Insert (c, FALSE) ELSE Dialogs.res := Dialogs.noPanelSelected END; IF Dialogs.res # 0 THEN Dialogs.Error ("DialogClocks") END; END Insert; BEGIN Init END DialogAnalogClocks.